/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.seata.discovery.registry;

import org.apache.seata.common.ConfigurationKeys;
import org.apache.seata.common.Constants;
import org.apache.seata.common.loader.EnhancedServiceLoader;
import org.apache.seata.common.util.StringUtils;
import org.apache.seata.config.ConfigurationFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;

/**
 * The type multiple Registry factory.
 */
public class MultiRegistryFactory {

    private static final Logger LOGGER = LoggerFactory.getLogger(MultiRegistryFactory.class);

    /**
     * Gets instances.
     *
     * @return the instance list
     */
    public static List<RegistryService> getInstances() {
        return MultiRegistryFactoryHolder.INSTANCES;
    }

    private static List<RegistryService> buildRegistryServices() {
        List<RegistryService> registryServices = new ArrayList<>();

        String registryTypeNamesStr =
                ConfigurationFactory.CURRENT_FILE_INSTANCE.getConfig(ConfigurationKeys.FILE_ROOT_REGISTRY
                        + ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR
                        + ConfigurationKeys.FILE_ROOT_TYPE);

        // If blank, use default configuration
        if (StringUtils.isBlank(registryTypeNamesStr)) {
            registryTypeNamesStr = RegistryType.File.name();
        }

        Set<String> registryTypeNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
        registryTypeNames.addAll(Arrays.asList(registryTypeNamesStr.split(Constants.REGISTRY_TYPE_SPLIT_CHAR)));

        if (registryTypeNames.size() > 1) {
            LOGGER.info("use multi registry center type: {}", registryTypeNames);
        }

        for (String registryTypeName : registryTypeNames) {
            RegistryType registryType = RegistryType.getType(registryTypeName);

            RegistryService registryService = EnhancedServiceLoader.load(
                            RegistryProvider.class,
                            Objects.requireNonNull(registryType).name())
                    .provide();
            registryServices.add(registryService);
        }
        return registryServices;
    }

    private static class MultiRegistryFactoryHolder {
        private static final List<RegistryService> INSTANCES = buildRegistryServices();
    }
}
